package com.chenxbook.modules.jbpm4.tool;

import com.chenxbook.modules.boot.constant.CommonConstant;
import com.chenxbook.modules.jbpm4.assign.JumpTaskCommand;
import lombok.Data;
import org.apache.commons.collections4.CollectionUtils;
import org.jbpm.api.ManagementService;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.TaskService;
import org.jbpm.api.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>className: JbpmTaskTool</p>
 * <p>description: 自定义工作处理工具类</p>
 *
 * @author chenxbook
 * @version 1.0.0
 * @date 2020-05-23 19:48
 */
@Data
@Component("jbpmTaskTool")
public class JbpmTaskTool {

    private static final Logger log = LoggerFactory.getLogger(JbpmTaskTool.class);

    /**
     * ProcessEngine-流程引擎对象
     * <br> 工作流引擎根据配置产生
     */
    @Autowired
    @Qualifier("processEngine")
    private ProcessEngine processEngine;


    /**
     * ManagementService-流程管理服务接口
     * <br> 提供异步工作（Job）相关的执行和查询操作
     */
    @Autowired
    @Qualifier(value = "managementService")
    private ManagementService managementService;

    /**
     * TaskService-人工任务服务接口
     * <br> 提供对任务（Task）的创建、提交、查询、保存、删除等操作。
     */
    @Autowired
    @Qualifier("taskService")
    private TaskService taskService;


    /***
     * 获取指定用户的任务列表
     *
     * @param userId  任务ID
     * @author chenxbook
     * @date 2020/10/31 15:11
     * @return
     */
    public List<Task> findPersonalTasks(String userId) {
        log.info("parameters，userId:{}", userId);
        List<Task> personalTasks = taskService.findPersonalTasks(userId);
        if (CollectionUtils.isNotEmpty(personalTasks)) {
            personalTasks.stream().forEach(task ->
                    log.info("taskId=[{}],taskName=[{}]", task.getId(), task.getName())
            );
        }
        return personalTasks;
    }

    /**
     * Description
     * <br> 获取任务
     *
     * @param pid      流程实例ID
     * @param assignee 任务分配者
     * @date 2021-09-05
     * @author your name
     **/
    public Task getTask(String pid, String assignee) {
        return taskService.createTaskQuery().processInstanceId(pid).assignee(assignee).uniqueResult();
    }


    /***
     * 获取指定用户的分组任务列表
     *
     * @param userId  任务ID
     * @author chenxbook
     * @date 2020/10/31 15:11
     * @return
     */
    public List<Task> findGroupTasks(String userId) {
        log.info("parameters，userId:{}", userId);
        List<Task> groupTasks = taskService.findGroupTasks(userId);
        if (CollectionUtils.isNotEmpty(groupTasks)) {
            groupTasks.stream().forEach(task ->
                    log.info("taskId=[{}],taskName=[{}]", task.getId(), task.getName())
            );
        }
        return groupTasks;
    }


    /***
     * 获取任务变量
     *
     * @author chenxbook
     * @date 2020/5/24 23:11
     * @param taskId  任务ID
     * @return java.util.Map<java.lang.String, java.lang.Object>
     */
    public Map<String, Object> getTaskVariables(String taskId) {
        //获取变量名
        Set<String> variableNames = taskService.getVariableNames(taskId);
        Map<String, Object> variables = new HashMap<>(16);
        if (CollectionUtils.isNotEmpty(variableNames)) {
            //读取任务变量
            variables = taskService.getVariables(taskId, variableNames);
        }
        return variables;
    }


    /***
     * 处理任务
     *
     * @author chenxbook
     * @date 2020/5/24 11:33
     * @param taskId 任务ID
     * @return java.lang.String
     */
    public String dealWithTask(String taskId) {
        log.info("parameters，taskId:{}", taskId);
        if (taskId != null) {
            taskService.completeTask(taskId);
            return CommonConstant.EXECUTE_SUCCESS;
        }
        return CommonConstant.EXECUTE_FAILED;
    }


    /***
     * 处理任务
     *
     * @author chenxbook
     * @param taskId 任务ID
     * @param outcome 流出转移
     */
    public void dealWithTask(String taskId, String outcome) {
        log.info("parameters，taskId:{}，outcome:{}", taskId, outcome);
        taskService.completeTask(taskId, outcome);
    }


    /***
     * 处理任务(任务变量)
     *
     * @author chenxbook
     * @date 2020/5/24 11:33
     * @param taskId 任务ID
     * @param variables 任务变量
     * @return java.lang.String
     */
    public String dealWithTask2(String taskId, Map<String, Object> variables) {
        log.info("parameters，taskId:{}，variables:{}", taskId, variables);
        if (taskId != null) {
            taskService.completeTask(taskId, variables);
            return CommonConstant.EXECUTE_SUCCESS;
        }
        return CommonConstant.EXECUTE_FAILED;
    }

    /****
     * 处理任务(任务变量+流出转移)
     * <br> outcome 决定任务完成后流程流向哪个流出"转移"
     *
     * @author
     * @date 2020/5/24 11:39
     * @param taskId 任务ID
     * @param outcome 流出转移
     * @param variables 任务变量
     * @return java.lang.String
     */
    public String dealWithTask3(String taskId, String outcome, Map<String, Object> variables) {
        String paramMsg = MessageFormat.format("parameters，taskId:{0}，outcome：{1}，variables:{2}，", taskId, outcome, variables);
        log.info(paramMsg);
        if (taskId != null) {
            taskService.completeTask(taskId, outcome, variables);
            return CommonConstant.EXECUTE_SUCCESS;
        }
        return CommonConstant.EXECUTE_FAILED;
    }

    /***
     * 执行任务跳转
     *
     * @author
     * @date 2020/5/24 16:56
     * @param taskId 任务ID
     * @param targetName 目标节点名称
     * @param variables  任务变量
     */
    public void completeJumpTask(String taskId, String targetName, Map<String, Object> variables) {
        JumpTaskCommand compositeCmd = new JumpTaskCommand();
        compositeCmd.setVariables(variables);
        compositeCmd.setTaskId(taskId);
        compositeCmd.setTargetName(targetName);
        this.processEngine.execute(compositeCmd);
    }

    /***
     * 接收任务
     *
     * @param taskId 任务ID
     * @param userId 用户ID
     * @author
     * @date 2020/10/31 16:56
     */
    public void acceptTask(String taskId, String userId) {
        log.info("parameters，taskId:{}，userId:{}", taskId, userId);
        taskService.takeTask(taskId, userId);
    }

    /**
     * Description
     * <br> 处理客户端要求退回任务的请求
     *
     * @param taskId            任务ID
     * @param rollbackToActName 退回任务的节点名称
     * @date 2021-09-05
     * @author your name
     **/
    public void completeTaskRollback(String taskId, String rollbackToActName) {
        Task task = taskService.getTask(taskId);
        String outcome = task.getActivityName() + " to " + rollbackToActName;
        taskService.completeTask(taskId, outcome);
    }

}